home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_300 / 334_02 / parse2.c < prev    next >
Text File  |  1991-02-04  |  7KB  |  414 lines

  1. /*
  2.  *
  3.  *    G N U P L O T  --  parse.c
  4.  *
  5.  *  Copyright (C) 1986 Colin Kelley, Thomas Williams
  6.  *
  7.  *  You may use this code as you wish if credit is given and this message
  8.  *  is retained.
  9.  *
  10.  *  Please e-mail any useful additions to vu-vlsi!plot so they may be
  11.  *  included in later releases.
  12.  *
  13.  *  This file should be edited with 4-column tabs!  (:set ts=4 sw=4 in vi)
  14.  */
  15.  
  16. #include <stdio.h>
  17. #include <setjmp.h>
  18. #include <signal.h>
  19. #include <errno.h>
  20. #include "plot.h"
  21.  
  22. extern BOOLEAN undefined;
  23.  
  24. #ifndef vms
  25. extern int errno;
  26. #endif
  27.  
  28. extern int next_function,c_function /* next available space in udft */;
  29. extern int num_tokens,c_token;
  30. extern struct lexical_unit token[];
  31. extern char dummy_var[];
  32. extern struct at_type *curr_at;
  33.  
  34. struct value *pop(),*integer(),*complex();
  35.  
  36. static struct at_type temp_at;
  37. static jmp_buf fpe_env;
  38.  
  39. #define dummy (struct value *) 0
  40.  
  41. fpe()
  42. {
  43.     (void) signal(SIGFPE, fpe);
  44.     undefined = TRUE;
  45.     longjmp(fpe_env, TRUE);
  46. }
  47.  
  48. evaluate_at(at,valptr)
  49. struct at_type *at;
  50. struct value *valptr;
  51. {
  52.     undefined = FALSE;
  53.     errno = 0;
  54.     reset_stack();
  55.     if (setjmp(fpe_env))
  56.         return;                /* just bail out */
  57.     (void) signal(SIGFPE, fpe);    /* catch core dumps on FPEs */
  58.  
  59.     execute_at(at);
  60.  
  61.     (void) signal(SIGFPE, SIG_DFL);
  62.  
  63.     if (errno == EDOM || errno == ERANGE) {
  64.         undefined = TRUE;
  65.     } else {
  66.         (void) pop(valptr);
  67.         check_stack();
  68.     }
  69. }
  70.  
  71.  
  72. struct value *
  73. const_express(valptr)
  74. struct value *valptr;
  75. {
  76. register int tkn = c_token;
  77.     if (END_OF_COMMAND)
  78.         int_error("constant expression required",c_token);
  79.     build_at(&temp_at);    /* make a temporary action table */
  80.     evaluate_at(&temp_at,valptr);    /* run it and send answer back */
  81.     if (undefined) {
  82.         int_error("undefined value",tkn);
  83.     }
  84.     return(valptr);
  85. }
  86.  
  87.  
  88. build_at(at)    /* build full expressions */
  89. struct at_type *at;
  90. {
  91.     curr_at = at;        /* set global variable */
  92.     curr_at->count = 0;        /* reset action table !!! */
  93.     express();
  94. }
  95.  
  96.  
  97. express()  /* full expressions */
  98. {
  99.     xterm();
  100.     xterms();
  101. }
  102.  
  103. xterm()  /* NEW!  ? : expressions */
  104. {
  105.     aterm();
  106.     aterms();
  107. }
  108.  
  109.  
  110. aterm()
  111. {
  112.     bterm();
  113.     bterms();
  114. }
  115.  
  116.  
  117. bterm()
  118. {
  119.     cterm();
  120.     cterms();
  121. }
  122.  
  123.  
  124. cterm()
  125. {
  126.     dterm();
  127.     dterms();
  128. }
  129.  
  130.  
  131. dterm()
  132. {    
  133.     eterm();
  134.     eterms();
  135. }
  136.  
  137.  
  138. eterm()
  139. {
  140.     fterm();
  141.     fterms();
  142. }
  143.  
  144.  
  145. fterm()
  146. {
  147.     gterm();
  148.     gterms();
  149. }
  150.  
  151.  
  152. gterm()
  153. {
  154.     hterm();
  155.     hterms();
  156. }
  157.  
  158.  
  159. hterm()
  160. {
  161.     unary(); /* - things */
  162.     iterms(); /* * / % */
  163. }
  164.  
  165.  
  166. factor()
  167. {
  168. register int value;
  169. struct value a, real_value;
  170.  
  171.     if (equals(c_token,"(")) {
  172.         c_token++;
  173.         express();
  174.         if (!equals(c_token,")")) 
  175.             int_error("')' expected",c_token);
  176.         c_token++;
  177.     }
  178.     else if (isnumber(c_token)) {
  179.         convert(&real_value,c_token);
  180.         c_token++;
  181.         add_action(PUSHC, &real_value);
  182.     }
  183.     else if (isletter(c_token)) {
  184.         if ((c_token+1 < num_tokens)  && equals(c_token+1,"(")) {
  185.         value = standard(c_token);
  186.             if (value) {    /* it's a standard function */
  187.                 c_token += 2;
  188.                 express();
  189.                 if (!equals(c_token,")"))
  190.                     int_error("')' expected",c_token);
  191.                 c_token++;
  192.                 add_action(value,dummy);
  193.             }
  194.             else {
  195.                 value = user_defined(c_token);
  196.                 c_token += 2;
  197.                 express();
  198.                 if (!equals(c_token,")")) 
  199.                     int_error("')' expected",c_token);
  200.                 c_token++;
  201.                 add_action(CALL,integer(&a,value));
  202.             }
  203.         }
  204.         else {
  205.             if (equals(c_token,dummy_var)) {
  206.                 value = c_function;
  207.                 c_token++;
  208.                 add_action(PUSHD,integer(&a,value));
  209.             }
  210.             else {
  211.                 value = add_value(c_token);
  212.                 c_token++;
  213.                 add_action(PUSH,integer(&a,value));
  214.             }
  215.         }
  216.     } /* end if letter */
  217.     else
  218.         int_error("invalid expression ",c_token);
  219.  
  220.     /* add action code for ** operator */
  221.     if (equals(c_token,"**")) {
  222.             c_token++;
  223.             unary();
  224.             add_action(POWER,dummy);
  225.     }
  226. }
  227.  
  228.  
  229.  
  230. xterms()
  231. {  /* create action code for ? : expressions */
  232.  
  233.     while (equals(c_token,"?")) {
  234.         c_token++;
  235.         express();
  236.         if (!equals(c_token,":")) 
  237.             int_error("expecting ':'",c_token);
  238.         c_token++;
  239.         express();
  240.         add_action(TERNIARY,dummy);
  241.     }
  242. }
  243.  
  244.  
  245. aterms()
  246. {  /* create action codes for || operator */
  247.  
  248.     while (equals(c_token,"||")) {
  249.         c_token++;
  250.         aterm();
  251.         add_action(LOR,dummy);
  252.     }
  253. }
  254.  
  255.  
  256. bterms()
  257. { /* create action code for && operator */
  258.  
  259.     while (equals(c_token,"&&")) {
  260.         c_token++;
  261.         bterm();
  262.         add_action(LAND,dummy);
  263.     }
  264. }
  265.  
  266.  
  267. cterms()
  268. { /* create action code for | operator */
  269.  
  270.     while (equals(c_token,"|")) {
  271.         c_token++;
  272.         cterm();
  273.         add_action(BOR,dummy);
  274.     }
  275. }
  276.  
  277.  
  278. dterms()
  279. { /* create action code for ^ operator */
  280.  
  281.     while (equals(c_token,"^")) {
  282.         c_token++;
  283.         dterm();
  284.         add_action(XOR,dummy);
  285.     }
  286. }
  287.  
  288.  
  289. eterms()
  290. { /* create action code for & operator */
  291.  
  292.     while (equals(c_token,"&")) {
  293.         c_token++;
  294.         eterm();
  295.         add_action(BAND,dummy);
  296.     }
  297. }
  298.  
  299.  
  300. fterms()
  301. { /* create action codes for == and != operators */
  302.  
  303.     while (TRUE) {
  304.         if (equals(c_token,"==")) {
  305.             c_token++;
  306.             fterm();
  307.             add_action(EQ,dummy);
  308.         }
  309.         else if (equals(c_token,"!=")) {
  310.             c_token++;
  311.             fterm(); 
  312.             add_action(NE,dummy); 
  313.         }
  314.         else break;
  315.     }
  316. }
  317.  
  318.  
  319. gterms()
  320. { /* create action code for < > >= or <= operators */
  321.     
  322.     while (TRUE) {
  323.         /* I hate "else if" statements */
  324.         if (equals(c_token,">")) {
  325.             c_token++;
  326.             gterm();
  327.             add_action(GT,dummy);
  328.         }
  329.         else if (equals(c_token,"<")) {
  330.             c_token++;
  331.             gterm();
  332.             add_action(LT,dummy);
  333.         }        
  334.         else if (equals(c_token,">=")) {
  335.             c_token++;
  336.             gterm();
  337.             add_action(GE,dummy);
  338.         }
  339.         else if (equals(c_token,"<=")) {
  340.             c_token++;
  341.             gterm();
  342.             add_action(LE,dummy);
  343.         }
  344.         else break;
  345.     }
  346.  
  347. }
  348.  
  349.  
  350.  
  351. hterms()
  352. { /* create action codes for + and - operators */
  353.  
  354.     while (TRUE) {
  355.             if (equals(c_token,"+")) {
  356.                 c_token++;
  357.                 hterm();
  358.                 add_action(PLUS,dummy);
  359.             }
  360.             else if (equals(c_token,"-")) {
  361.                 c_token++;
  362.                 hterm();
  363.                 add_action(MINUS,dummy);
  364.             }
  365.             else break;
  366.     }
  367. }
  368.  
  369.  
  370. iterms()
  371. { /* add action code for * / and % operators */
  372.  
  373.     while (TRUE) {
  374.             if (equals(c_token,"*")) {
  375.                 c_token++;
  376.                 unary();
  377.                 add_action(MULT,dummy);
  378.             }
  379.             else if (equals(c_token,"/")) {
  380.                 c_token++;
  381.                 unary();
  382.                 add_action(DIV,dummy);
  383.             }
  384.             else if (equals(c_token,"%")) {
  385.                 c_token++;
  386.                 unary();
  387.                 add_action(MOD,dummy);
  388.             }
  389.             else break;
  390.     }
  391. }
  392.  
  393.  
  394. unary()
  395. { /* add code for unary operators */
  396.     if (equals(c_token,"!")) {
  397.         c_token++;
  398.         unary();
  399.         add_action(LNOT,dummy);
  400.     }
  401.     else if (equals(c_token,"~")) {
  402.         c_token++;
  403.         unary();
  404.         add_action(BNOT,dummy);
  405.     }
  406.     else if (equals(c_token,"-")) {
  407.         c_token++;
  408.         unary();
  409.         add_action(UMINUS,dummy);
  410.     }
  411.     else 
  412.         factor();
  413. }
  414.